package com.utils.info.util.hhy;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.SneakyThrows;

import javax.servlet.http.HttpServletResponse;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Optional;

/**
 * 导出pdf工具类
 *
 * @author hhy
 * @date 2021/11/08 10:47:43
 * @desc 描述： 导出pdf的工具类、包含标题，表格，图片，下载
 */
@SuppressWarnings("ALL")
public class DownloadPDFUtil {

    private static final Integer fontSizeTitle = 20; //大标题字体大小
    private static final Integer fontSizeHeading = 16; //小标题字体大小
    private static final Integer spacingAfterHeading = 10; //离上一段落 空的行数
    private static final Integer tableWidthFinal = 100; //默认宽度

    /**
     * 设置标题
     *
     * @param document 文档
     * @param baseFont 字体 （字体，编码，颜色）
     * @param title    标题文字
     * @param fontSize 字体大小
     */
    @SneakyThrows
    public static void setTitle(Document document, BaseFont baseFont, String title, Integer fontSize) {
        checkNotNull(document, baseFont, title);
        fontSize = Optional.ofNullable(fontSize).orElse(fontSizeTitle);//判断字体大小不为空
        Font font = new Font(baseFont, fontSize, Font.BOLD); //设置字体
        Paragraph paragraph = new Paragraph(title, font); //标题
        paragraph.setAlignment(Element.ALIGN_CENTER); //标题居中
        document.add(paragraph); //写入pdf中
    }

    /**
     * 设置小标题
     *
     * @param document     文档
     * @param baseFont     字体 （字体，编码，颜色）
     * @param heading      小标题文字
     * @param spacingAfter 离上一段落 空的行数
     * @param fontSize     字体大小
     */
    public static void setHeading(Document document, BaseFont baseFont, String heading, Integer fontSize, Integer spacingAfter) throws DocumentException {
        checkNotNull(document, baseFont, heading);
        fontSize = Optional.ofNullable(fontSize).orElse(fontSizeHeading);//判断字体大小不为空
        spacingAfter = Optional.ofNullable(spacingAfter).orElse(spacingAfterHeading);//判断离上一段落 空的行数不为空
        Font font = new Font(baseFont, fontSize, Font.BOLD); //设置字体
        Paragraph paragraph = new Paragraph(heading, font); //标题
        paragraph.setSpacingAfter(spacingAfter); //离上一段落 空的行数
        paragraph.setAlignment(Element.ALIGN_LEFT); //标题居左（左对齐）
        document.add(paragraph); //写入pdf中
    }

    /**
     * 添加表格
     *
     * @param document 文档
     * @param baseFont 字体 （字体，编码，颜色）
     * @param num      表格列数
     * @param fontSize 字体大小
     * @param texts    正文
     */
    @SneakyThrows
    public static void setTable(Document document, BaseFont baseFont, Integer num, Integer fontSize, List<String> texts) {
        checkNotNull(document, baseFont, num, texts);
        fontSize = Optional.ofNullable(fontSize).orElse(fontSizeHeading);//判断字体大小不为空

        Font font = new Font(baseFont, fontSize, Font.BOLD); //设置字体

        PdfPTable table = new PdfPTable(num);//创建pdf表格
        table.setWidthPercentage(100);//设置表格具体宽度
        table.setSpacingBefore(10f);//前间距
        table.setSpacingAfter(10f);//后间距

        for (String text : texts) {
            PdfPCell cell = new PdfPCell(new Paragraph(text, font));
            cell.setUseDescender(true);//设置垂直居中
            cell.setVerticalAlignment(Element.ALIGN_CENTER);//设置垂直居中
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平对齐
            table.addCell(cell);
        }
        document.add(table);
    }

    /**
     * 添加本地图片
     *
     * @param document   文档
     * @param num        表格列数
     * @param tableWidth 表格宽度
     * @param url        图片地址
     * @param images     图片名称
     * @param width      图片宽度
     * @param height     图片长度
     */
    @SneakyThrows
    public static void setLocalImages(Document document, Integer num, Integer tableWidth, String url, List<String> images, Float width, Float height) {
        checkNotNull(document, num, url, images);
        tableWidth = Optional.ofNullable(tableWidth).orElse(tableWidthFinal);//判断字体大小不为空

        PdfPTable table = new PdfPTable(num);//创建pdf表格
        table.setWidthPercentage(tableWidth);//设置表格具体宽度
        table.setSpacingBefore(10f);//前间距
        table.setSpacingAfter(10f);//后间距

        for (String image : images) {
            Image instance = Image.getInstance(url + image);//获取图片
            width = Optional.ofNullable(width).orElse(instance.getWidth());//判断宽度是否为空，为空获取源图宽度
            height = Optional.ofNullable(height).orElse(instance.getHeight());//判断高度是否为空，为空获取源图高度
            PdfPCell cell = new PdfPCell(instance);//把图片添加到表格中
            cell.disableBorderSide(15);//隐藏边框
            cell.setUseDescender(true);//设置垂直居中
            cell.setVerticalAlignment(Element.ALIGN_CENTER);//设置垂直居中
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平对齐
            table.addCell(cell);
        }
        document.add(table);
    }

    /**
     * 添加网络图片
     *
     * @param document   文档
     * @param num        表格列数
     * @param tableWidth 表格宽度
     * @param urls       图片地址
     * @param width      图片宽度
     * @param height     图片长度
     */
    @SneakyThrows
    public static void setNetworkImages(Document document, Integer num, Integer tableWidth, List<String> urls, Float width, Float height) {
        checkNotNull(document, num, urls);
        tableWidth = Optional.ofNullable(tableWidth).orElse(tableWidthFinal);//判断字体大小不为空

        PdfPTable table = new PdfPTable(num);//创建pdf表格
        table.setWidthPercentage(tableWidth);//设置表格具体宽度
        table.setSpacingBefore(10f);//前间距
        table.setSpacingAfter(10f);//后间距

        for (String url : urls) {
            URL url1 = new URL(url);
            Image image = Image.getInstance(url1);//获取图片
            width = Optional.ofNullable(width).orElse(image.getWidth());//判断宽度是否为空，为空获取源图宽度
            height = Optional.ofNullable(height).orElse(image.getHeight());//判断高度是否为空，为空获取源图高度
            image.scaleAbsolute(width, height);//设置图片长度，宽度
            PdfPCell cell = new PdfPCell(image);//把图片添加到表格中
            cell.disableBorderSide(15);//隐藏边框
            cell.setUseDescender(true);//设置垂直居中
            cell.setVerticalAlignment(Element.ALIGN_CENTER);//设置垂直居中
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平对齐
            table.addCell(cell);
        }
        document.add(table);
    }

    @SneakyThrows
    public static void export(Document document, PdfWriter writer, String fileName, HttpServletResponse resp) {
        //处理乱码
        resp.setContentType("application/vnd.ms-excel;charset=UTF-8");
        resp.addHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + ".pdf");
        //下载刷新
        writer.flush();
        document.close();
    }

    /**
     * 判断参数是否为空
     *
     * @param o 参数
     * @throws NullPointerException 异常
     */
    public static void checkNotNull(Object... o) throws NullPointerException {
        if (o != null && o.length > 0) {
            for (Object obj : o) {
                if (obj == null || "".equals(obj.toString())) {
                    throw new NullPointerException("传入的数据不能为null或者为空");
                }
            }
        }
    }
}
